package com.turbo.cloud.ums.web.logic;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.turbo.cloud.core.api.Result;
import com.turbo.cloud.core.base.PageQuery;
import com.turbo.cloud.core.exception.BusinessException;
import com.turbo.cloud.core.utils.BeanListUtils;
import com.turbo.cloud.core.utils.StrValidateUtil;
import com.turbo.cloud.ums.captcha.HappyCaptcha;
import com.turbo.cloud.ums.constants.UMSConstants;
import com.turbo.cloud.core.security.utils.SecurityUtil;
import com.turbo.cloud.core.security.jwt.JwtUtils;
import com.turbo.cloud.core.security.jwt.JwtProperties;
import com.turbo.cloud.ums.utils.DeptTreeUtil;
import com.turbo.cloud.ums.utils.ComponentUtil;
import com.turbo.cloud.ums.web.client.MinioFileClient;
import com.turbo.cloud.ums.web.model.component.UmsMenuComponentVO;
import com.turbo.cloud.ums.web.model.component.UmsComponentVO;
import com.turbo.cloud.ums.web.model.role.UmsRoleVO;
import com.turbo.cloud.ums.web.model.user.UmsUserPwdQO;
import com.turbo.cloud.ums.web.model.user.UmsUserQO;
import com.turbo.cloud.ums.web.model.user.UmsUserTokenVO;
import com.turbo.cloud.ums.web.model.user.UmsUserVO;
import com.turbo.cloud.ums.web.service.*;
import com.turbo.cloud.ums.utils.HappyCaptchaRequestUtil;
import com.turbo.cloud.core.utils.PageQueryUtil;
import com.turbo.cloud.ums.web.entity.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 用户 逻辑处理类
 * </p>
 *
 * @author zhangluning
 * @since 2022-08-13
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class UserLogic {

    final JwtProperties jwtProperties;
    final IUmsUserService umsUserService;
    final IUmsRoleService umsRoleService;
    final IUmsUserRoleRelationService umsUserRoleRelationService;
    final IUmsRolePermissionRelationService umsRolePermissionRelationService;
    final IUmsPermissionComponentRelationService umsPermissionComponentRelationService;
    final IUmsDeptService umsDeptService;
    final IUmsMenuService umsMenuService;
    final IUmsComponentService umsComponentService;
    final IUmsUserDeptRelationService umsUserDeptRelationService;
    final IUmsUserHomeService umsHomeMenuService;
    final PasswordEncoder passwordEncoder;
    final MinioFileClient minioFileClient;

    /**
     * 根据用户ID，查询用户信息
     *
     * @param userId 用户ID
     * @return 用户实体
     */
    public UmsUserVO loadUserByUserId(String userId) {
        UmsUser umsUser = umsUserService.getById(userId);
        if (Objects.isNull(umsUser)) {
            return null;
        } else {
            UmsUserVO umsUserVO = new UmsUserVO();
            BeanUtils.copyProperties(umsUser, umsUserVO);

            LambdaQueryWrapper<UmsUserRoleRelation> userRoleRelationLQW = new LambdaQueryWrapper<>();
            userRoleRelationLQW.eq(UmsUserRoleRelation::getUserId, userId);
            List<UmsUserRoleRelation> userRoleRelationList = umsUserRoleRelationService.list(userRoleRelationLQW);

            if (!CollectionUtils.isEmpty(userRoleRelationList)) {
                List<String> roleIds = userRoleRelationList.stream().map(UmsUserRoleRelation::getRoleId).filter(roleId -> StrUtil.isNotBlank(roleId)).toList();

                if (!CollectionUtils.isEmpty(roleIds)) {
                    umsUserVO.setRoleIds(roleIds);

                    LambdaQueryWrapper<UmsRolePermissionRelation> rolePermissionRelationLQW = new LambdaQueryWrapper<>();
                    rolePermissionRelationLQW.in(UmsRolePermissionRelation::getRoleId, roleIds);
                    List<UmsRolePermissionRelation> rolePermissionRelationList = umsRolePermissionRelationService.list(rolePermissionRelationLQW);
                    if (!CollectionUtils.isEmpty(rolePermissionRelationList)) {
                        List<String> permissionIds = rolePermissionRelationList.stream().map(UmsRolePermissionRelation::getPermissionId).toList();
                        umsUserVO.setPermissionIds(permissionIds);
                    }
                }
            }

            LambdaQueryWrapper<UmsUserDeptRelation> userDeptRelationLQW = new LambdaQueryWrapper<>();
            userDeptRelationLQW.eq(UmsUserDeptRelation::getUserId, userId);
            List<UmsUserDeptRelation> umsUserDeptRelationList = umsUserDeptRelationService.list(userDeptRelationLQW);

            if (Objects.nonNull(umsUserDeptRelationList) && !umsUserDeptRelationList.isEmpty()) {
                List<String> deptIdList = umsUserDeptRelationList.stream().map(UmsUserDeptRelation::getDeptId).filter(deptId -> StrUtil.isNotBlank(deptId)).toList();
                umsUserVO.setDeptIds(deptIdList);
            }

            return umsUserVO;
        }
    }

    /**
     * 模糊查询用户分页列表
     *
     * @param pageQuery 分页查询实体
     * @return Page
     */
    public PageQuery<UmsUserVO> queryUserPage(PageQuery<UmsUserQO> pageQuery) {
        String systemId = SecurityUtil.getCurrentSystemId();

        UmsUserQO umsUserQO = PageQueryUtil.getPageParam(pageQuery, UmsUserQO::new);

        /*
         * 模糊查询条件
         */
        LambdaQueryWrapper<UmsUser> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(UmsUser::getSystemId, systemId);

        userLambdaQueryWrapper.like(StrUtil.isNotBlank(umsUserQO.getUsernameByLike()), UmsUser::getUsername, umsUserQO.getUsernameByLike());
        userLambdaQueryWrapper.like(StrUtil.isNotBlank(umsUserQO.getRealNameByLike()), UmsUser::getRealName, umsUserQO.getRealNameByLike());
        userLambdaQueryWrapper.orderByDesc(UmsUser::getCreatedDate);

        Page<UmsUser> userPage = null;
        if (!CollectionUtils.isEmpty(umsUserQO.getDeptIds())) {
            LambdaQueryWrapper<UmsUserDeptRelation> userDeptRelationLQW = new LambdaQueryWrapper<>();

            // Vue 树形组件，半选中状态父级是不返回ID的，所有如果deptIds是父级ID要找一下它的的子级是否被选中
            LambdaQueryWrapper<UmsDept> deptLambdaQueryWrapper = new LambdaQueryWrapper<>();
            /* 这里考虑：
             * 1、数据库迁移，用SQL实现递归，移植性不好
             * 2、根据系统隔离，系统下部门不是很多，in的索引不会失效
             */
            deptLambdaQueryWrapper.in(UmsDept::getSystemId, systemId);
            List<UmsDept> deptList = umsDeptService.list(deptLambdaQueryWrapper);

            if (!CollectionUtils.isEmpty(umsUserQO.getDeptIds())) {
                List<String> deptIds = new ArrayList<>();
                DeptTreeUtil.getChildrenDeptIds(umsUserQO.getDeptIds().get(0), deptList, deptIds);
                if (!CollectionUtils.isEmpty(deptIds)) {
                    umsUserQO.getDeptIds().addAll(deptIds);
                }
            }

            userDeptRelationLQW.in(UmsUserDeptRelation::getDeptId, umsUserQO.getDeptIds());
            List<UmsUserDeptRelation> userDeptRelationList = umsUserDeptRelationService.list(userDeptRelationLQW);

            if (Objects.nonNull(userDeptRelationList) && !userDeptRelationList.isEmpty()) {
                List<String> userIds = userDeptRelationList.stream().map(UmsUserDeptRelation::getUserId).toList();

                userLambdaQueryWrapper.in(UmsUser::getId, userIds);
                userPage = umsUserService.page(pageQuery.toPage(), userLambdaQueryWrapper);
            }
        } else {
            userPage = umsUserService.page(pageQuery.toPage(), userLambdaQueryWrapper);
        }

        PageQuery<UmsUserVO> pageQueryResult = PageQueryUtil.toPageQuery(userPage, UmsUserVO::new);
        for (UmsUserVO userVO : pageQueryResult.getRecords()) {
            userVO.setMobileNoByMask(userVO.getMobileNo());
            userVO.setEmailByMask(userVO.getEmail());
            userVO.setPassword(null);

            LambdaQueryWrapper<UmsUserRoleRelation> userRoleRelationLQW = new LambdaQueryWrapper<>();
            userRoleRelationLQW.eq(UmsUserRoleRelation::getUserId, userVO.getId());
            List<UmsUserRoleRelation> userRoleRelationList = umsUserRoleRelationService.list(userRoleRelationLQW);
            List<String> roleIds = userRoleRelationList.stream().map(UmsUserRoleRelation::getRoleId).toList();
            userVO.setRoleIds(roleIds);

            LambdaQueryWrapper<UmsUserDeptRelation> userDeptRelationLQW = new LambdaQueryWrapper<>();
            userDeptRelationLQW.eq(UmsUserDeptRelation::getUserId, userVO.getId());
            List<UmsUserDeptRelation> userDeptRelationList = umsUserDeptRelationService.list(userDeptRelationLQW);
            List<String> deptIds = userDeptRelationList.stream().map(UmsUserDeptRelation::getDeptId).toList();
            userVO.setDeptIds(deptIds);

            /*
             * 获取首页地址
             */
            LambdaQueryWrapper<UmsUserHome> homeMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
            homeMenuLambdaQueryWrapper.eq(UmsUserHome::getUserId, userVO.getId());
            UmsUserHome umsUserHome = umsHomeMenuService.getOne(homeMenuLambdaQueryWrapper);
            if (Objects.nonNull(umsUserHome) && StrUtil.isNotBlank(umsUserHome.getMenuId())) {
                UmsMenu umsMenu = umsMenuService.getById(umsUserHome.getMenuId());
                if (Objects.nonNull(umsMenu) && StrUtil.isNotBlank(umsMenu.getRouterPath())) {
                    userVO.setHomePath(umsMenu.getRouterPath());
                    userVO.setHomeMenuId(umsMenu.getId());
                }
            }

            if (StrUtil.isNotBlank(userVO.getIcon())) {
                Result<String> result = minioFileClient.getFileUrl(userVO.getIcon(), UMSConstants.MINIO_BUCKET_NAME);
                userVO.setIconFileUrl(result.getResult());
            }
        }
        return pageQueryResult;
    }


    /**
     * 用户登录
     *
     * @param umsUserQO 用户登录实体
     * @param request   请求体
     * @return UmsUserTokenVO
     */
    public UmsUserTokenVO login(UmsUserQO umsUserQO, HttpServletRequest request) {
        if (StrUtil.isBlank(umsUserQO.getUsername())) {
            throw new BusinessException("用户名不能为空");
        }
        if (StrUtil.isBlank(umsUserQO.getPassword())) {
            throw new BusinessException("密码不能为空");
        }

        String userId = umsUserQO.getSystemId() + UMSConstants.STR_SEPARATOR_UNDERLINE + umsUserQO.getUsername();

        boolean isCheckHappyCaptcha = HappyCaptchaRequestUtil.showHappyCaptcha(request);
        if (isCheckHappyCaptcha || StrUtil.isNotBlank(umsUserQO.getVerifyCode())) {
            boolean flag = HappyCaptcha.verification(request, umsUserQO.getVerifyCode(), true);
            if (!flag) {
                throw new BusinessException("验证码不正确");
            } else {
                HappyCaptcha.remove(request);
            }
        }

        /*
         * 根据用户名查询用户信息
         */
        UmsUserVO umsUserVO = loadUserByUserId(userId);
        /*
         * 比对密码正确性
         */
        if (Objects.isNull(umsUserVO) || !passwordEncoder.matches(umsUserQO.getPassword(), umsUserVO.getPassword())) {
            int loginFailCount = HappyCaptchaRequestUtil.getLoginFailCount(request);
            HappyCaptchaRequestUtil.setLoginFailCount(request);
            throw new BusinessException("用户名或密码不正确（" + (loginFailCount + 1) + "次）");
        }

        /*
         * 生成JWTToken
         */
        UmsUserTokenVO umsUserTokenVO = new UmsUserTokenVO();
        umsUserTokenVO.setAccessToken(jwtProperties.getTokenHead() + JwtUtils.generateTokenExpire(umsUserVO, jwtProperties.getSecret(), jwtProperties.getExpiration()));

        HappyCaptchaRequestUtil.removeLoginFailCount(request);
        return umsUserTokenVO;
    }

    /**
     * 用户登录
     *
     * @param umsUserQO 用户登录实体
     * @param request   请求体
     * @return UmsUserTokenVO
     */
    public UmsUserTokenVO loginByValidStrength(UmsUserQO umsUserQO, HttpServletRequest request) {
        if (StrUtil.isBlank(umsUserQO.getUsername())) {
            throw new BusinessException("用户名不能为空");
        }
        if (StrUtil.isBlank(umsUserQO.getPassword())) {
            throw new BusinessException("密码不能为空");
        }

        String userId = umsUserQO.getSystemId() + UMSConstants.STR_SEPARATOR_UNDERLINE + umsUserQO.getUsername();

        boolean isCheckHappyCaptcha = HappyCaptchaRequestUtil.showHappyCaptcha(request);
        if (isCheckHappyCaptcha || StrUtil.isNotBlank(umsUserQO.getVerifyCode())) {
            boolean flag = HappyCaptcha.verification(request, umsUserQO.getVerifyCode(), true);
            if (!flag) {
                throw new BusinessException("验证码不正确");
            } else {
                HappyCaptcha.remove(request);
            }
        }

        /*
         * 根据用户名查询用户信息
         */
        UmsUserVO umsUserVO = loadUserByUserId(userId);
        /*
         * 比对密码正确性
         */
        if (Objects.isNull(umsUserVO) || !passwordEncoder.matches(umsUserQO.getPassword(), umsUserVO.getPassword())) {
            int loginFailCount = HappyCaptchaRequestUtil.getLoginFailCount(request);
            HappyCaptchaRequestUtil.setLoginFailCount(request);
            throw new BusinessException("用户名或密码不正确（" + (loginFailCount + 1) + "次）");
        }

        /*
         * 生成JWTToken
         */
        UmsUserTokenVO umsUserTokenVO = new UmsUserTokenVO();
        umsUserTokenVO.setAccessToken(jwtProperties.getTokenHead() + JwtUtils.generateTokenExpire(umsUserVO, jwtProperties.getSecret(), jwtProperties.getExpiration()));

        HappyCaptchaRequestUtil.removeLoginFailCount(request);
        return umsUserTokenVO;
    }

    /**
     * 用户登出
     */
    public void logout() {
        SecurityContextHolder.clearContext();
    }

    /**
     * 当前用户信息
     *
     * @return UmsUserVO
     */
    public UmsUserVO queryCurrentUserInfo() {
        String userId = SecurityUtil.getCurrentUserId();
        UmsUser umsUser = umsUserService.getById(userId);

        umsUser.setPassword(null);
        UmsUserVO umsUserVO = new UmsUserVO();
        BeanUtils.copyProperties(umsUser, umsUserVO);

        /*
         * 获取首页地址
         */
        LambdaQueryWrapper<UmsUserHome> homeMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        homeMenuLambdaQueryWrapper.eq(UmsUserHome::getUserId, userId);
        UmsUserHome umsUserHome = umsHomeMenuService.getOne(homeMenuLambdaQueryWrapper);
        if (Objects.nonNull(umsUserHome) && StrUtil.isNotBlank(umsUserHome.getMenuId())) {
            UmsMenu umsMenu = umsMenuService.getById(umsUserHome.getMenuId());
            if (Objects.nonNull(umsMenu) && StrUtil.isNotBlank(umsMenu.getRouterPath())) {
                umsUserVO.setHomePath(umsMenu.getRouterPath());
                umsUserVO.setHomeMenuId(umsMenu.getId());
            }
        }

        /*
         * 获取角色列表
         */
        LambdaQueryWrapper<UmsUserRoleRelation> userRoleRelationLQW = new LambdaQueryWrapper<>();
        userRoleRelationLQW.eq(UmsUserRoleRelation::getUserId, userId);
        List<UmsUserRoleRelation> userRoleRelationList = umsUserRoleRelationService.list(userRoleRelationLQW);

        if (Objects.nonNull(userRoleRelationList)) {
            List<String> userRoleIds = userRoleRelationList.stream().map(UmsUserRoleRelation::getRoleId).toList();
            umsUserVO.setRoleIds(userRoleIds);

            LambdaQueryWrapper<UmsRole> roleLambdaQueryWrapper = new LambdaQueryWrapper<>();
            roleLambdaQueryWrapper.in(UmsRole::getId, userRoleIds);
            List<UmsRole> roleList = umsRoleService.list(roleLambdaQueryWrapper);

            if (Objects.nonNull(roleList)) {

                List<UmsRoleVO> roleVOList = new ArrayList<>();
                BeanListUtils.copyList(roleList, roleVOList, UmsRoleVO::new);

                List<UmsMenuComponentVO> umsPermissionVOList = new ArrayList<>();
                List<String> permissionIds = new ArrayList<>();
                // 根据用户角色查询按钮权限关系模型
                if (!CollectionUtils.isEmpty(userRoleRelationList)) {
                    for (UmsRoleVO umsRoleVO : roleVOList) {
                        LambdaQueryWrapper<UmsRolePermissionRelation> rolePermissionRelationLQW = new LambdaQueryWrapper<>();
                        rolePermissionRelationLQW.eq(UmsRolePermissionRelation::getRoleId, umsRoleVO.getId());
                        List<UmsRolePermissionRelation> rolePermissionList = umsRolePermissionRelationService.list(rolePermissionRelationLQW);

                        if (!CollectionUtils.isEmpty(rolePermissionList)) {
                            List<String> permissionIdsByRoleId = rolePermissionList.stream().map(UmsRolePermissionRelation::getPermissionId).toList();

                            permissionIds.addAll(permissionIdsByRoleId);

                            LambdaQueryWrapper<UmsPermissionComponentRelation> permissionComponentRelationLQW = new LambdaQueryWrapper<>();
                            permissionComponentRelationLQW.in(UmsPermissionComponentRelation::getPermissionId, permissionIdsByRoleId);
                            List<UmsPermissionComponentRelation> umsPermissionComponentRelationList = umsPermissionComponentRelationService.list(permissionComponentRelationLQW);

                            if (!CollectionUtils.isEmpty(umsPermissionComponentRelationList)) {
                                List<String> menuIds = new ArrayList<>();
                                for (UmsPermissionComponentRelation umsPermissionComponentRelation : umsPermissionComponentRelationList) {
                                    if (!menuIds.contains(umsPermissionComponentRelation.getMenuId())) {
                                        UmsMenu umsMenu = umsMenuService.getById(umsPermissionComponentRelation.getMenuId());
                                        if (Objects.nonNull(umsMenu)) {
                                            UmsMenuComponentVO controlPermissionVO = new UmsMenuComponentVO();
                                            controlPermissionVO.setMenuId(umsMenu.getId());
                                            controlPermissionVO.setRouterPath(umsMenu.getRouterPath());
                                            umsPermissionVOList.add(controlPermissionVO);
                                        }
                                        menuIds.add(umsPermissionComponentRelation.getMenuId());
                                    }
                                    UmsComponent umsComponent = umsComponentService.getById(umsPermissionComponentRelation.getComponentId());
                                    if (Objects.nonNull(umsComponent)) {
                                        UmsComponentVO umsComponentVO = new UmsComponentVO();
                                        BeanUtils.copyProperties(umsComponent, umsComponentVO);
                                        ComponentUtil.assemblePermissionList(umsPermissionVOList, umsPermissionComponentRelation.getMenuId(), umsComponentVO);
                                    }
                                }
                            }

                            umsUserVO.setComponentPermissions(umsPermissionVOList);
                            umsUserVO.setPermissionIds(permissionIds);
                        }
                    }
                }
            }
        }

        /*
         * 获取部门列表
         */
        LambdaQueryWrapper<UmsUserDeptRelation> userDeptRelationLQW = new LambdaQueryWrapper<>();
        userDeptRelationLQW.eq(UmsUserDeptRelation::getUserId, userId);
        List<UmsUserDeptRelation> userDeptRelationList = umsUserDeptRelationService.list(userDeptRelationLQW);

        if (!CollectionUtils.isEmpty(userDeptRelationList)) {
            List<String> userDeptIds = userDeptRelationList.stream().map(UmsUserDeptRelation::getDeptId).toList();
            umsUserVO.setDeptIds(userDeptIds);
        }

        if (StrUtil.isNotBlank(umsUserVO.getIcon())) {
            Result<String> result = minioFileClient.getFileUrl(umsUserVO.getIcon(), UMSConstants.MINIO_BUCKET_NAME);
            umsUserVO.setIconFileUrl(result.getResult());
        }

        return umsUserVO;
    }

    /**
     * 验证用户名是否OK
     *
     * @return UmsUserVO
     */
    public Boolean verifyUsername(UmsUserQO umsUserQO) {
        if (Validator.hasChinese(umsUserQO.getUsername())) {
            throw new BusinessException("用户名不能包含汉字");
        } else if (StrValidateUtil.hasSpecialChar(umsUserQO.getUsername())) {
            throw new BusinessException("用户名不能包含特殊字符");
        } else if (umsUserQO.getUsername().toLowerCase().contains(UMSConstants.STR_USERNAME_SPECIAL_SPELLING)) {
            throw new BusinessException("用户名不能包含特殊拼写");
        } else if (umsUserQO.getUsername().length() >= UMSConstants.STR_USERNAME_LENGTH) {
            throw new BusinessException("用户名不能大于" + UMSConstants.STR_USERNAME_LENGTH + "位");
        }
        return true;
    }

    /**
     * 新增用户
     *
     * @param umsUserQO 实体
     * @return UmsUserQO
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean createUser(UmsUserQO umsUserQO) {
        if (StrUtil.isBlank(umsUserQO.getSystemId())) {
            String systemId = SecurityUtil.getCurrentSystemId();
            umsUserQO.setSystemId(systemId);
        }

        String userId = umsUserQO.getSystemId() + "_" + umsUserQO.getUsername();
        umsUserQO.setId(userId);

        LambdaQueryWrapper<UmsUser> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(UmsUser::getId, umsUserQO.getId());
        UmsUser umsUserTmp = umsUserService.getOne(userLambdaQueryWrapper);
        if (Objects.nonNull(umsUserTmp)) {
            throw new BusinessException("用户名已经存在请更换");
        }

        userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(UmsUser::getSystemId, SecurityUtil.getCurrentSystemId());
        userLambdaQueryWrapper.eq(UmsUser::getMobileNo, umsUserQO.getMobileNo());

        UmsUser umsUserTmpOfMobile = umsUserService.getOne(userLambdaQueryWrapper);
        if (Objects.nonNull(umsUserTmpOfMobile)) {
            throw new BusinessException("此手机号已经绑定其他用户");
        }

        UmsUser umsUser = new UmsUser();
        BeanUtils.copyProperties(umsUserQO, umsUser);

        umsUser.setPassword(passwordEncoder.encode(umsUser.getPassword()));

        boolean result = umsUserService.save(umsUser);
        if (!result) {
            throw new BusinessException("新增用户失败");
        }

        bindUserRoleRelation(false, umsUserQO.getId(), umsUserQO.getRoleIds());
        bindUserDeptRelation(false, umsUserQO.getId(), umsUserQO.getDeptIds());
        bindUserHomeMenuRelation(false, umsUserQO.getId(), umsUserQO.getHomeMenuId());
        return true;
    }

    /**
     * 修改用户
     *
     * @param umsUserQO 实体
     * @return UmsUserQO
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean modifyUser(UmsUserQO umsUserQO) {
        if (StrUtil.isBlank(umsUserQO.getSystemId())) {
            String systemId = SecurityUtil.getCurrentSystemId();
            umsUserQO.setSystemId(systemId);
        }

        String userId = umsUserQO.getSystemId() + "_" + umsUserQO.getUsername();
        umsUserQO.setId(userId);

        UmsUser umsUser = new UmsUser();
        BeanUtils.copyProperties(umsUserQO, umsUser);

        UmsUser umsUserTmpOfMe = umsUserService.getById(userId);
        if (!umsUserTmpOfMe.getMobileNo().equals(umsUserQO.getMobileNo())) {
            LambdaQueryWrapper<UmsUser> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userLambdaQueryWrapper.eq(UmsUser::getSystemId, SecurityUtil.getCurrentSystemId());
            userLambdaQueryWrapper.eq(UmsUser::getMobileNo, umsUserQO.getMobileNo());

            UmsUser umsUserTmpOfMobile = umsUserService.getOne(userLambdaQueryWrapper);
            if (Objects.nonNull(umsUserTmpOfMobile)) {
                throw new BusinessException("此手机号已经绑定其他用户");
            }
        }

        boolean result = umsUserService.updateById(umsUser);
        if (!result) {
            throw new BusinessException("修改用户失败");
        }

        bindUserRoleRelation(true, umsUserQO.getId(), umsUserQO.getRoleIds());
        bindUserDeptRelation(true, umsUserQO.getId(), umsUserQO.getDeptIds());
        bindUserHomeMenuRelation(true, umsUserQO.getId(), umsUserQO.getHomeMenuId());
        return true;
    }

    /**
     * 删除用户
     *
     * @param id 用户ID
     * @return boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean removeUserById(String id) {
        if (StrUtil.isBlank(id)) {
            throw new BusinessException("用户ID不能为空");
        }

        // 删除首页
        LambdaQueryWrapper<UmsUserHome> userHomeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userHomeLambdaQueryWrapper.eq(UmsUserHome::getUserId, id);
        boolean resultUserHome = umsHomeMenuService.remove(userHomeLambdaQueryWrapper);

        // 删除部门
        LambdaQueryWrapper<UmsUserDeptRelation> userDeptLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userDeptLambdaQueryWrapper.eq(UmsUserDeptRelation::getUserId, id);
        boolean resultUserDept = umsUserDeptRelationService.remove(userDeptLambdaQueryWrapper);

        boolean result = umsUserService.removeById(id);
        if (!resultUserHome || !resultUserDept || !result) {
            throw new BusinessException("修改用户失败");
        }
        return true;
    }

    /**
     * 绑定用户和角色关系
     *
     * @param isUpdate 是否修改
     * @param userId   用户ID
     * @param roleIds  角色IDs
     */
    private void bindUserRoleRelation(boolean isUpdate, String userId, List<String> roleIds) {
        List<UmsUserRoleRelation> userRoleRelationList = new ArrayList<>();
        for (String roleId : roleIds) {
            UmsUserRoleRelation userRoleRelation = new UmsUserRoleRelation();
            userRoleRelation.setUserId(userId);
            userRoleRelation.setRoleId(roleId);
            userRoleRelationList.add(userRoleRelation);
        }

        if (isUpdate) {
            LambdaQueryWrapper<UmsUserRoleRelation> userRoleRelationLQW = new LambdaQueryWrapper<>();
            userRoleRelationLQW.eq(UmsUserRoleRelation::getUserId, userId);
            umsUserRoleRelationService.remove(userRoleRelationLQW);
        }

        boolean batchSaveUserRoleRelation = umsUserRoleRelationService.saveBatch(userRoleRelationList);
        if (!batchSaveUserRoleRelation) {
            throw new BusinessException("新增用户和角色关系失败");
        }
    }

    /**
     * 绑定用户和部门关系
     *
     * @param isUpdate 是否修改
     * @param userId   用户ID
     * @param roleIds  角色IDs
     */
    private void bindUserDeptRelation(boolean isUpdate, String userId, List<String> roleIds) {
        List<UmsUserDeptRelation> userDeptRelationList = new ArrayList<>();
        for (String roleId : roleIds) {
            UmsUserDeptRelation userDeptRelation = new UmsUserDeptRelation();
            userDeptRelation.setUserId(userId);
            userDeptRelation.setDeptId(roleId);
            userDeptRelationList.add(userDeptRelation);
        }

        if (isUpdate) {
            LambdaQueryWrapper<UmsUserDeptRelation> userDeptRelationLQW = new LambdaQueryWrapper<>();
            userDeptRelationLQW.eq(UmsUserDeptRelation::getUserId, userId);
            umsUserDeptRelationService.remove(userDeptRelationLQW);
        }

        boolean batchSaveUserDeptRelation = umsUserDeptRelationService.saveBatch(userDeptRelationList);
        if (!batchSaveUserDeptRelation) {
            throw new BusinessException("新增用户和部门关系失败");
        }
    }

    /**
     * 绑定用户和首页关系
     *
     * @param isUpdate 是否修改
     * @param userId   用户ID
     * @param menuId   菜单ID
     */
    private void bindUserHomeMenuRelation(boolean isUpdate, String userId, String menuId) {

        UmsUserHome umsUserHome = new UmsUserHome();
        umsUserHome.setUserId(userId);
        umsUserHome.setMenuId(menuId);

        if (isUpdate) {
            LambdaQueryWrapper<UmsUserHome> homeMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
            homeMenuLambdaQueryWrapper.eq(UmsUserHome::getUserId, userId);
            umsHomeMenuService.remove(homeMenuLambdaQueryWrapper);
        }

        boolean saveUserDeptRelation = umsHomeMenuService.save(umsUserHome);
        if (!saveUserDeptRelation) {
            throw new BusinessException("新增用户和首页关系失败");
        }
    }

    /**
     * 修改用户
     *
     * @param umsUserPwdQO 实体
     * @return Boolean
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean modifyUserPwd(UmsUserPwdQO umsUserPwdQO) {
        String userId = SecurityUtil.getCurrentUserId();
        if (!umsUserPwdQO.getNewPassword().equals(umsUserPwdQO.getConfirmPassword())) {
            throw new BusinessException("新密码和确认密码不一致");
        }
        UmsUser umsUser = umsUserService.getById(userId);
        /*
         * 验证用户是否存在
         */
        if (Objects.isNull(userId)) {
            throw new BusinessException("当前用户不存在");
        }
        /*
         * 比对密码正确性
         */
        if (!passwordEncoder.matches(umsUserPwdQO.getPassword(), umsUser.getPassword())) {
            throw new BusinessException("当前密码不正确");
        }
        umsUser.setPassword(passwordEncoder.encode(umsUserPwdQO.getNewPassword()));
        boolean result = umsUserService.updateById(umsUser);
        if (!result) {
            throw new BusinessException("修改用户密码失败");
        }

        return true;
    }
}
